import re
import csv
from logging import Logger
from pathlib import Path
from typing import List, Dict, Any
from performance.runner.constants import RESOURCE_MONITOR_ROUND


class ResourceLogParser:
    def __init__(self,  resource_log_path: Path, logger: Logger):
        self.resource_log_path = resource_log_path
        self.logger = logger


    @staticmethod
    def _parse_log_line(line: str) -> Dict[str, str]:
        def convert_cpu_memory_unit(result: Dict[str, str]) -> str:
            cpu, memory = result['cpu'], result['memory']
            if 'n' in result['cpu']:
                cpu = int(cpu.replace('n', ''))
                cpu //= 1000000 # nano to milli
                result['cpu'] = str(cpu)
            if 'Ki' in result['memory']:
                memory = int(memory.replace('Ki', ''))
                memory //= 1000 # Ki to Mi
                result['memory'] = str(memory)
            if 'Mi' in result['memory']:
                memory = int(memory.replace('Mi', ''))
                result['memory'] = str(memory)
            return result

        # 格式: namespace: xxx, Pod: xxx, CPU占用: xxx , 内存占用: xxx
        pattern = r'namespace:\s*([^,]+),\s*Pod:\s*([^,]+),\s*CPU占用:\s*([^,]+)\s*,\s*内存占用:\s*([^,]+)'
        match = re.search(pattern, line)
        if match.group(3).strip() == 'None' or match.group(4).strip() == 'None':
            return None
        if match:
            return convert_cpu_memory_unit({
                'namespace': match.group(1).strip(),
                'pod': match.group(2).strip(),
                'cpu': match.group(3).strip(),
                'memory': match.group(4).strip()
            })
        return None


    def _process_log_file(self, log_file: Path) -> List[List[str]]:
        """处理单个日志文件"""
        data = {}
        with open(log_file, 'r', encoding='utf-8') as f:
            for line in f.readlines():
                line = line.strip()
                if not line or line.startswith('='):  # 跳过空行和分隔符
                    continue
                parsed = self._parse_log_line(line)
                if not parsed:
                    continue
                key = f'{parsed['namespace']}_{parsed['pod']}'
                if not data.get(key, None):
                    data[key] = {'cpu': [parsed['cpu']], 'memory': [parsed['memory']]}
                else:
                    data[key]['cpu'].append(parsed['cpu'])
                    data[key]['memory'].append(parsed['memory'])
        result = []
        for key, value in data.items():
            result_line = key.split('_') + \
                [sum(map(int, value['cpu'])) / len(value['cpu']), \
                sum(map(int, value['memory'])) / len(value['memory'])] + \
                value['cpu'] + value['memory']
            result.append(result_line)
        return result


    def process_all_logs(self) -> List[str]:
        """处理所有找到的日志文件"""
        log_files = []
        # 遍历base_path下的所有子文件夹
        for item in self.resource_log_path.iterdir():
            sample_file = item / 'sample.log'
            log_files.append(sample_file)
        self.logger.info(f"找到 {len(log_files)} 个日志文件")

        all_data = []
        for log_file in log_files:
            self.logger.info(f"处理 resource monitor sample 文件: {log_file}")
            file_data = self._process_log_file(log_file)
            all_data.extend(file_data)
            self.logger.info(f"提取了 {len(file_data)} 条记录")

        return all_data


    def save_to_csv(self, data: List[str], output_path: Path):
        """将解析的数据保存为CSV文件"""
        if not data:
            self.logger.warning("没有数据需要保存")
            return
            
        with open(output_path, 'w', newline='', encoding='utf-8') as csvfile:
            fieldnames = ['namespace', 'pod', 'cpu_avg (milliCores)', 'memory_avg (MiB)'] +\
                            ['cpu (millicores)'] * RESOURCE_MONITOR_ROUND + \
                            ['memory (MiB)'] * RESOURCE_MONITOR_ROUND
            writer = csv.writer(csvfile)
            writer.writerow(fieldnames)
            writer.writerows(data)
            
        self.logger.info(f"已保存 {len(data)} 条记录到 {output_path}")
